<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Canvas连线</title>
  <style media="screen">
    * {
      margin: 0;
      padding: 0;
    }

    #wrap {
      width: 100%;
    }

    #canvas {
      display: block;
    }
  </style>
</head>

<body>
  <div id="wrap">
    <canvas id="canvas"></canvas>
  </div>

  <script type="text/javascript">
    // 获取窗口宽高
    var h = window.innerHeight,
      w = window.innerWidth;
    document.getElementById('wrap').style.height = h + 'px';

    var con = document.getElementById('canvas');
    // 设置画布
    var c = con.getContext('2d');
    // 给画布设置宽高，此处必须是setAttribute，设置style会导致画出来的图像变形
    con.setAttribute('width', w);
    con.setAttribute('height', h);
    // 监听窗口resize事件，动态设置宽高
    window.onresize = function() {
      h = window.innerHeight;
      w = window.innerWidth;
      document.getElementById('wrap').style.height = h + 'px';
      con.setAttribute('width', w);
      con.setAttribute('height', h);
    }

    // 创建一个圆点对象
    function dot() {
      this.x = Math.random() * w; // X轴坐标，0 - w
      this.y = Math.random() * h; // Y轴坐标， 0 - y
      this.r = Math.random() * 2 + 2; // 圆点半径， 5 - 10
      this.vx = Math.random() * 2 - 1; // X轴加速度，-1 - 1
      this.vy = Math.random() * 2 - 1; // Y轴加速度，-1 - 1
    }

    // 圆点合集
    var dots = [];
    for (var i = 0; i < 250; i++) {
      dots.push(new dot());
    }

    // 画图方法
    function drow() {
      c.clearRect(0, 0, w, h); //清除画布，再开始画下面的圆，否则会连成一条直线
      for (var i = 0; i < dots.length; i++) {
        var dot = dots[i];
        // 开始画圆
        c.beginPath();
        c.arc(dot.x, dot.y, dot.r, 0, 2 * Math.PI); //canvas画圆公式：arc(x,y,r,start,stop)
        c.fillStyle = 'rgba(0,0,0,.2)'; //设置填充颜色
        c.fill(); //填充

        // 匀速运动
        dot.x += dot.vx;
        dot.y += dot.vy;

        //超出屏幕边界时反向运动
        if (dot.x > w || dot.x < 0) {
          dot.vx = dot.vx * -1;
        }
        if (dot.y > w || dot.y < 0) {
          dot.vy = dot.vy * -1;
        }

        // 再次循环，将每个点之间的距离进行计算
        for (var j = 0; j < dots.length; j++) {
          var d = dots[j];
          var s = Math.sqrt(Math.pow((d.x - dot.x), 2) + Math.pow((d.y - dot.y), 2) - d.r / 2 - dot.r / 2); //利用勾股定理计算出距离
          // 如果两点之间的距离小于某个值，就将两点进行连线
          if (s != NaN && s < 100) {
            c.beginPath();
            c.moveTo(dot.x, dot.y);  // 线的起点
            c.lineTo(d.x, d.y);  // 线的终点
            c.strokeStyle = 'rgba(255,80,120,.2)';
            c.stroke();
          }
        }
      }
      requestAnimationFrame(drow);  // 帧动画
    }
    requestAnimationFrame(drow);  // 与函数内部的帧动画方法形成一个循环，可以实现定时器的效果
  </script>
</body>

</html>
